package testcircuits;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Test;

import circuits.Component;
import circuits.Input;

public class TestComponent {

	private Component component;
	private Input input1;
	private Input input2;
	private static final String INPUT_NAME_1 = "E1";
	private static final String INPUT_NAME_2 = "E2";
	
	@Before
	public void setUp(){
		this.component = new MockComponent();
		this.input1 = new StubOffInput();
		this.input2 = new StubOffInput();
	}
	
	@Test
	public void addInputNameOnceReturnTrue(){
		assertTrue(this.component.addInputName(INPUT_NAME_1));
	}
	
	@Test
	public void addSameInputNameReturnFalse(){
		this.component.addInputName(INPUT_NAME_1);
		
		assertFalse(this.component.addInputName(INPUT_NAME_1));
	}
	
	@Test
	public void addDifferentInputNameReturnTrue(){
		this.component.addInputName(INPUT_NAME_1);
		
		assertTrue(this.component.addInputName(INPUT_NAME_2));
	}
	
	@Test
	public void removeInputNameNonExistentReturnFalse(){
		assertFalse(this.component.removeInputName(INPUT_NAME_1));
	}
	
	@Test
	public void addAndRemoveInputNameReturnTrue(){
		this.component.addInputName(INPUT_NAME_1);
		
		assertTrue(this.component.removeInputName(INPUT_NAME_1));
	}
	
	@Test
	public void connectNonExistentInputReturnFalse(){
		assertFalse(this.component.connectInput(INPUT_NAME_1,this.input1));
	}
	
	@Test
	public void addInputNameConnectInputReturnTrue(){
		this.component.addInputName(INPUT_NAME_1);
		
		assertTrue(this.component.connectInput(INPUT_NAME_1,this.input1));
	}
	
	@Test
	public void addInputNamesConnectInputToFirstThenToSecondReturnTrue(){
		this.component.addInputName(INPUT_NAME_1);
		this.component.addInputName(INPUT_NAME_2);
		
		this.component.connectInput(INPUT_NAME_1,this.input1);
		assertTrue(this.component.connectInput(INPUT_NAME_1, this.input2));
	}
	
	@Test
	public void addInputNamesConnectSameInputToBothReturnTrue(){
		this.component.addInputName(INPUT_NAME_1);
		this.component.addInputName(INPUT_NAME_2);
		
		this.component.connectInput(INPUT_NAME_1,this.input1);
		assertTrue(this.component.connectInput(INPUT_NAME_2, this.input1));
	}
	
	@Test
	public void addAndRemoveInputNameConnectInputReturnFalse(){
		this.component.addInputName(INPUT_NAME_1);
		this.component.removeInputName(INPUT_NAME_1);
		
		assertFalse(this.component.connectInput(INPUT_NAME_1,this.input1));
	}
	
	class MockComponent extends Component{
		@Override
		public void generateOutput(){}
		@Override
		public void readInputValues(){}
	}
}
